﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	/// <summary>
	/// VoteClasses 类。
	/// </summary>
	public static partial class VoteClasses
	{
		public const string INFO_TYPE = "VoteClass";



		#region GetIdentifier
		public static int? GetIdentifier(int? siteId, string classCode)
		{
			if (!siteId.HasValue) return null;
			return GetIdentifier(siteId.Value, classCode);
		}

		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="classCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		public static int? GetIdentifier(int siteId, string classCode)
		{
			string key = siteId + "-" + classCode;
			Dictionary<string, int?> ids = GenericCacheContainer.Instance.VoteClassIdByCodeDictionary;
			if (ids.ContainsKey(key))
				return ids[key];

			lock (ids)
			{
				if (!ids.ContainsKey(key))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					int? value = dc.VoteClasses.GetIdentifier(siteId, classCode);
					try
					{
						ids[key] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						ids.Clear();
						ids[key] = value;
					}
				}
			}
			return ids[key];
		}

		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="classCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		internal static int? GetIdentifier(this System.Data.Linq.Table<VoteClass> o, int siteId, string classCode)
		{
			var q = from p in o
					where p.SiteId == siteId && p.ClassCode == classCode
					select (int?)p.ClassId;
			return q.SingleOrDefault();
		}
		#endregion



		#region GetNameById
		public static string GetNameById(this System.Data.Linq.Table<VoteClass> o, int classId)
		{
			var q = from p in o
					where p.ClassId == classId
					select p.ClassName;
			return q.SingleOrDefault();
		}

		public static string GetNameById(int classId)
		{
			Dictionary<int, string> names = GenericCacheContainer.Instance.VoteClassNameByIdDictionary;
			if (names.ContainsKey(classId))
				return names[classId];

			lock (names)
			{
				if (!names.ContainsKey(classId))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					string value = dc.VoteClasses.GetNameById(classId);
					try
					{
						names[classId] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						names.Clear();
						names[classId] = value;
					}
				}
			}
			return names[classId];
		}

		public static string GetNameById(int siteId, string classCode)
		{
			int? classId = GetIdentifier(siteId, classCode);
			if (!classId.HasValue) return null;
			return GetNameById(classId.Value);
		}

		public static string GetNameById(int? siteId, string classCode)
		{
			if (!siteId.HasValue) return null;
			return GetNameById(siteId.Value, classCode);
		}
		#endregion
		
		
		
		#region GetItem
		/// <summary>
		/// 根据标识获取指定的调查类别。
		/// </summary>
		/// <param name="o">调查类别集合。</param>
		/// <param name="typeId">获取的调查类别标识 ClassId。</param>
		/// <returns>获取的信息项。</returns>
		public static VoteClass GetItem(this System.Data.Linq.Table<VoteClass> o, int typeId)
		{
			return o.SingleOrDefault(p => p.ClassId == typeId);
		}

		public static VoteClass GetItem(int typeId)
		{
			return GetItem(typeId, false);
		}

		public static VoteClass GetItem(int typeId, bool trackObject)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = trackObject;
			return dc.VoteClasses.GetItem(typeId);
		}



		public static VoteClass GetItem(this System.Data.Linq.Table<VoteClass> o, int siteId, string classCode)
		{
			return o.SingleOrDefault(p => p.SiteId == siteId && p.ClassCode == classCode);
		}

		public static VoteClass GetItem(int siteId, string classCode)
		{
			return GetItem(siteId, classCode, false);
		}

		public static VoteClass GetItem(int siteId, string classCode, bool trackObject)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = trackObject;
			return dc.VoteClasses.GetItem(siteId, classCode);
		}
		#endregion



		#region GetChildren
		public static List<VoteClass> GetRoots(this System.Data.Linq.Table<VoteClass> o, int siteId)
		{
			return o.Where(p => p.SiteId == siteId && p.PClassId == null).ToList();
		}

		public static List<VoteClass> GetRoots(int siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.VoteClasses.GetRoots(siteId);
		}



		public static List<VoteClass> GetChildren(this System.Data.Linq.Table<VoteClass> o, int siteId, int? pClassId)
		{
			if (pClassId.HasValue)
				return o.Where(p => p.SiteId == siteId && p.PClassId == pClassId.Value).ToList();
			else
				return o.Where(p => p.SiteId == siteId && p.PClassId == null).ToList();
		}

		public static List<VoteClass> GetChildren(int siteId, int? pClassId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.VoteClasses.GetChildren(siteId, pClassId);
		}




		public static List<VoteClass> GetChildren(this System.Data.Linq.Table<VoteClass> o, int? pClassId)
		{
			if (pClassId.HasValue)
				return o.Where(p => p.PClassId == pClassId.Value).ToList();
			else
				return o.Where(p => p.PClassId == null).ToList();
		}

		public static List<VoteClass> GetChildren(int? pClassId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.VoteClasses.GetChildren(pClassId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的调查类别是否已经存在。
		/// </summary>
		/// <param name="o">调查类别集合。</param>
		/// <param name="typeId">验证的调查类别标识 ClassId。</param>
		/// <returns>布尔值表示指定的调查类别是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<VoteClass> o, int typeId)
		{
			return o.Any(p => p.ClassId == typeId);
		}



		/// <summary>
		/// 验证指定的调查类别代码是否已经存在。
		/// </summary>
		/// <param name="o">调查类别集合。</param>
		/// <param name="siteId">验证的调查类别标识 siteId。</param>
		/// <param name="typeCode">验证的调查类别代码。</param>
		/// <returns>布尔值表示指定的调查类别代码是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<VoteClass> o, int siteId, string typeCode)
		{
			return o.Any(p => p.SiteId == siteId && p.ClassCode == typeCode);
		}

		public static bool Exists(int siteId, string typeCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.VoteClasses.Exists(siteId, typeCode);
		}
		#endregion
	}



	/// <summary>
	/// VoteClasses 类操作部分。
	/// </summary>
	public static partial class VoteClasses
	{
		#region Insert
		/// <summary>
		/// 添加调查类别。
		/// </summary>
		/// <param name="insertedVoteClass">添加的调查类别。</param>
		/// <returns>添加的调查类别。</returns>
		public static VoteClass Insert(VoteClass insertedVoteClass)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			VoteClass voteClass = insertedVoteClass.ToNewEntity<VoteClass>();
			voteClass.CreatorId = Users.CurrentUserId;
			voteClass.CreationDate = DateTime.Now;

			GetInsertRight(dc, voteClass, true);	// 权限验证

			if (voteClass.PClassId != null)
			{
				VoteClass pVoteClass = dc.VoteClasses.GetItem(voteClass.PClassId.Value);
				if (pVoteClass == null)
					throw new ObjectNotExistsException(Res.VoteClasses_NotExistsParent);
				pVoteClass.ChildCount += 1;		// 上级节点的子节点数加1
			}
			dc.VoteClasses.InsertOnSubmit(voteClass);
			dc.SubmitChanges();

			// 注册权限
			RegisterVoteClassVoteReleasePermission(voteClass);

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Insert, INFO_TYPE, voteClass.ClassId.ToString(), PermissionCode.Insert.ToString(), voteClass.ClassName);

			// 返回只读数据
			return insertedVoteClass.FillByEntity(voteClass);
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedColumns = typeof(VoteClass).GetEntityColumnNames(new string[] {
				"ClassName",
				"Memo"
			}, true);

		/// <summary>
		/// 修改调查类别。
		/// </summary>
		/// <param name="updatedVoteClass">修改的调查类别。</param>
		/// <returns>修改的调查类别。</returns>
		public static VoteClass Update(VoteClass updatedVoteClass)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			VoteClass voteClass = dc.VoteClasses.GetItem(updatedVoteClass.ClassId);
			if (voteClass == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, voteClass, true);	// 权限验证

			voteClass.FillByEntity(updatedVoteClass, _updatedColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 注册权限
			RegisterVoteClassVoteReleasePermission(voteClass);

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Update, INFO_TYPE, voteClass.ClassId.ToString(), PermissionCode.Update.ToString(), voteClass.ClassName);

			// 返回只读数据
			return updatedVoteClass.FillByEntity(voteClass);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除调查类别。
		/// </summary>
		/// <param name="classId">删除的调查类别标识 ClassId。</param>
		public static void Delete(int classId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			VoteClass voteClass = dc.VoteClasses.GetItem(classId);
			if (voteClass == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, voteClass, true);	// 权限验证

			Delete(dc, voteClass);

			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, voteClass.ClassId.ToString(), PermissionCode.Delete.ToString(), voteClass.ClassName);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, VoteClass voteClass)
		{
			if (voteClass.Parent != null)
				voteClass.Parent.ChildCount -= 1;		// 上级节点数减1
			VoteClasses.DeleteByParent(dc, voteClass);	// 删除关联数据
			Votes.DeleteByParent(dc, voteClass);	// 删除关联数据
			dc.VoteClasses.DeleteOnSubmit(voteClass);

			// 删除权限注册
			Resource resource = dc.Resources.GetItem(VoteReleaseResourceCategoryId, voteClass.SiteId, GetVoteReleaseResourceCode(voteClass.ClassId));
			if (resource != null)
				Resources.Delete(dc, resource);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, VoteClass parent)
		{
			IEnumerable<VoteClass> e = parent.Children.AsEnumerable();
			foreach (VoteClass i in e)
				Delete(dc, i);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, Site parent)
		{
			IEnumerable<VoteClass> e = parent.VoteClasses.AsEnumerable();
			foreach (VoteClass i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// VoteClasses 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class VoteClasses
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加调查类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="voteClass">添加的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加调查类别的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, VoteClass voteClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Insert;
			bool b = dc.AccessController.GetUserIsHasPermission<VoteClass>(userName, voteClass, ResourceId, permissionCode, voteClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, voteClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有添加调查类别的权限。
		/// </summary>
		/// <param name="voteClass">添加的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加调查类别的权限。</returns>
		public static bool GetInsertRight(VoteClass voteClass, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), voteClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加调查类别的权限。
		/// </summary>
		/// <param name="voteClass">添加的调查类别对象。</param>
		/// <returns>布尔值表示当前用户是否有添加调查类别的权限。</returns>
		public static bool GetInsertRight(VoteClass voteClass)
		{
			return GetInsertRight(voteClass, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新调查类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="voteClass">更新的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新调查类别的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, VoteClass voteClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Update;
			bool b = dc.AccessController.GetUserIsHasPermission<VoteClass>(userName, voteClass, ResourceId, permissionCode, voteClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, voteClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有更新调查类别的权限。
		/// </summary>
		/// <param name="voteClass">更新的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新调查类别的权限。</returns>
		public static bool GetUpdateRight(VoteClass voteClass, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), voteClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新调查类别的权限。
		/// </summary>
		/// <param name="voteClass">更新的调查类别对象。</param>
		/// <returns>布尔值表示当前用户是否有更新调查类别的权限。</returns>
		public static bool GetUpdateRight(VoteClass voteClass)
		{
			return GetUpdateRight(voteClass, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除调查类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="voteClass">删除的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除调查类别的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, VoteClass voteClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Delete;
			bool b = dc.AccessController.GetUserIsHasPermission<VoteClass>(userName, voteClass, ResourceId, permissionCode, voteClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, voteClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除调查类别的权限。
		/// </summary>
		/// <param name="voteClass">删除的调查类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除调查类别的权限。</returns>
		public static bool GetDeleteRight(VoteClass voteClass, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), voteClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除调查类别的权限。
		/// </summary>
		/// <param name="voteClass">删除的调查类别对象。</param>
		/// <returns>布尔值表示当前用户是否有删除调查类别的权限。</returns>
		public static bool GetDeleteRight(VoteClass voteClass)
		{
			return GetDeleteRight(voteClass, false);
		}
		#endregion
	}




	/// <summary>
	/// VoteClasses 类后台管理部分。
	/// </summary>
	public static partial class VoteClasses
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, VoteClasses.ResourceId, (int)VoteClasses.PermissionCode.Update, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, VoteClasses.ResourceId, (int)VoteClasses.PermissionCode.Update, siteId);
		}


		public static PaginationInfo<List<VoteClass>> GetPaginationManageList(int? siteId, int? pClassId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.VoteClasses
					select p;

			if (siteId.HasValue)
				q = q.Where(p => p.SiteId == siteId.Value);

			if (pClassId.HasValue)
				q = q.Where(p => p.PClassId == pClassId.Value);
			else
				q = q.Where(p => p.PClassId == null);

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.ClassName.Contains(keyword));

			PaginationInfo<List<VoteClass>> pageInfo = new PaginationInfo<List<VoteClass>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
	}




	/// <summary>
	/// VoteClasses 类前台显示部分。
	/// </summary>
	public static partial class VoteClasses
	{
	}
}